home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet internetowy / Rozne / HTTrack 3.40-2 / httrack-3.40-2.exe / {app} / src_win / WinHTTrack / DirTreeView.cpp < prev    next >
C/C++ Source or Header  |  2004-01-24  |  21KB  |  750 lines

  1. // DirTreeView.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "winhttrack.h"
  6. #include "DirTreeView.h"
  7.  
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. extern "C" {
  15.   #include "HTTrackInterface.h"
  16.   #include "htsbase.h"
  17. };
  18.  
  19. #include "MainFrm.h"
  20.  
  21. CDirTreeView* this_DirTreeView=NULL;
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CDirTreeView
  25.  
  26. IMPLEMENT_DYNCREATE(CDirTreeView, CTreeView)
  27.  
  28. CDirTreeView::CDirTreeView()
  29. {
  30.   this_DirTreeView=this;
  31.   redraw_in_progress=0;
  32.   timer=0;
  33.   count_whandle=0;
  34.   docType="<nullType>";
  35. }
  36.  
  37. CDirTreeView::~CDirTreeView()
  38. {
  39.   WaitThreads();
  40.   this_DirTreeView=NULL;
  41.   if (imagelist.m_hImageList) {
  42.     imagelist.Detach();
  43.     imagelist.m_hImageList=NULL;
  44.   }
  45. }
  46.  
  47.  
  48. BEGIN_MESSAGE_MAP(CDirTreeView, CTreeView)
  49.     //{{AFX_MSG_MAP(CDirTreeView)
  50.     ON_WM_TIMER()
  51.     ON_WM_SHOWWINDOW()
  52.     ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
  53.     ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
  54.     ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
  55.     ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
  56.     ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown)
  57.     ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
  58.     ON_WM_KILLFOCUS()
  59.     ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
  60.     //}}AFX_MSG_MAP
  61. END_MESSAGE_MAP()
  62.  
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CDirTreeView drawing
  65.  
  66. void CDirTreeView::OnDraw(CDC* pDC)
  67. {
  68.     CDocument* pDoc = GetDocument();
  69.     // TODO: add draw code here
  70. }
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CDirTreeView diagnostics
  74.  
  75. #ifdef _DEBUG
  76. void CDirTreeView::AssertValid() const
  77. {
  78.     CTreeView::AssertValid();
  79. }
  80.  
  81. void CDirTreeView::Dump(CDumpContext& dc) const
  82. {
  83.     CTreeView::Dump(dc);
  84. }
  85. #endif //_DEBUG
  86.  
  87. /////////////////////////////////////////////////////////////////////////////
  88. // CDirTreeView message handlers
  89.  
  90.  
  91. BOOL CDirTreeView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
  92. {
  93.   dwStyle|=(TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_EDITLABELS);
  94.   //dwStyle|=(TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS|TVS_DISABLEDRAGDROP);
  95.   //
  96.   dwStyle&=(~(TVS_NOTOOLTIPS));     /* disabled */
  97.  
  98. /*
  99.   dwStyle|=(WS_DISABLED);
  100.   dwStyle&=(~(WS_VISIBLE));
  101. */
  102.  
  103.   int r=CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  104.  
  105.   GetTreeCtrl().SetImageList(&imagelist,TVSIL_NORMAL);
  106.   /*GetTreeCtrl().SetToolTips(&m_TreeViewToolTip);*/
  107.  
  108.   RefreshTree();
  109.   return r;
  110. }
  111.  
  112.  
  113. void CDirTreeView::RefreshTree() {
  114.   CTreeCtrl& tree=GetTreeCtrl();
  115.   if (!tree) return;   /* error */
  116.  
  117.   tree.DeleteAllItems();
  118.   int len=32768;
  119.   char* adr=(char*)malloc(len+4);
  120.   if (adr) {
  121.     if (GetLogicalDriveStrings(len,adr)>0) {
  122.       char*a=adr;
  123.       while(*a) {
  124.         char* next=a+strlen(a)+1;
  125.         if (*(a+strlen(a)-1)=='\\')
  126.           *(a+strlen(a)-1)='\0';
  127.         HTREEITEM it=tree.InsertItem(a);
  128.         if (it) {
  129.           tree.SetItemText(it,"");
  130.           tree.InsertItem("expanding..",it,TVI_SORT);
  131.          
  132.           // icone
  133.           char name[256];
  134.           strcpybuff(name,a);
  135.           strcatbuff(name,"\\");
  136.           SHFILEINFO info;
  137.           if (SHGetFileInfo(name,0,&info,sizeof(info),SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_SHELLICONSIZE | SHGFI_DISPLAYNAME)) {
  138.             //SHGetFileInfo(name,0,&info,sizeof(info),SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME | SHGFI_SHELLICONSIZE | SHGFI_DISPLAYNAME | SHGFI_ATTRIBUTES); 
  139.             tree.SetItemImage(it,info.iIcon,info.iIcon);
  140.             CString disp=info.szDisplayName;
  141.             if (disp.ReverseFind('('))
  142.               disp=disp.Left(disp.Find('('));
  143.             disp+="<"; disp+=a; disp+=">"; 
  144.             tree.SetItemText(it,disp);
  145.           }
  146.         }
  147.  
  148.         a=next;
  149.       }
  150.     }
  151.     free(adr);
  152.   }
  153.   
  154.   BuildTrackHandles();
  155. }
  156.  
  157. /* remise α zΘro */
  158. void CDirTreeView::ResetTree() {
  159.   if (!GetTreeCtrl()) return;   /* error */
  160.   RefreshTree();
  161.   StartTimer();
  162. }
  163.  
  164. /* attendre fin des threads refresh */
  165. void CDirTreeView::WaitThreads() {
  166.   /* attendre */
  167.   int w=0;
  168.   while((redraw_in_progress) && (w<10)) {
  169.     Sleep(100);
  170.     w++;
  171.   }
  172. }
  173.  
  174.  
  175. void CDirTreeView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
  176. {
  177.   *pResult = 0;
  178.   if (GetTreeCtrl().GetStyle() & WS_VISIBLE) {    /* sinon pas de refresh */
  179.     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  180.     
  181.     // find out what item is getting expanded, and send that to Expand(hItem, TVE_EXPAND)
  182.     if (pNMTreeView->hdr.code == TVN_ITEMEXPANDING)
  183.     {
  184.       HTREEITEM hIT = pNMTreeView->itemNew.hItem;
  185.       DestroyTrackHandles();
  186.       if (!RefreshDir(hIT))
  187.         *pResult = 1;
  188.       BuildTrackHandles();
  189.     }
  190.   }
  191. }
  192.  
  193. void CDirTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
  194. {
  195.   NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  196.   // find out what item is getting expanded, and send that to Expand(hItem, TVE_EXPAND)
  197.   if (pNMTreeView->hdr.code == TVN_SELCHANGED)
  198.   {
  199.     HTREEITEM hIT = pNMTreeView->itemNew.hItem;
  200.     CString st=GetItemPath(hIT);
  201.   
  202.     CWnd* top_window=this;
  203.     while(top_window->GetParent())
  204.       top_window=top_window->GetParent();
  205.     SetWindowTextCP(((CMainFrame*)top_window)->m_wndStatusBar, st);
  206.   }    
  207.   *pResult = 0;
  208. }
  209.  
  210.  
  211. void CDirTreeView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
  212. {
  213.   HTREEITEM selected=GetTreeCtrl().GetSelectedItem();
  214.   if (selected) {
  215.     if (!GetTreeCtrl().ItemHasChildren(selected)) {
  216.       CString name=GetItemPath(selected);
  217.       if (name.Right(1)=="\\")
  218.         name=name.Left(name.GetLength()-1);
  219.       DWORD attrb=GetFileAttributes(name);
  220.       if (attrb!=0xFFFFFFFF) {
  221.         if ( !(attrb & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY)) ) {
  222.           CWaitCursor wait;
  223.           if (docType.CompareNoCase(name.Right(docType.GetLength()))==0) {
  224.             CWinApp* app=AfxGetApp();
  225.             POSITION pos;
  226.             pos=app->GetFirstDocTemplatePosition();
  227.             CDocTemplate* templ = app->GetNextDocTemplate(pos);
  228.             pos=templ->GetFirstDocPosition();
  229.             CDocument* doc  = templ->GetNextDoc(pos);
  230.             if (doc) {
  231.               //if (doc->SaveModified()) {
  232.               AfxGetApp()->OpenDocumentFile(name);
  233.               //}
  234.             }
  235.           } else {
  236.             /* Lancer ShellEx en arriΦre plan */
  237.             AfxBeginThread(CDirTreeViewShellEx,new CString(name));
  238.           }
  239.         }
  240.       }
  241.     }
  242.   }
  243.   *pResult = 0;
  244. }
  245.  
  246. void CDirTreeView::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
  247. {
  248.   CTreeCtrl& tree=GetTreeCtrl();
  249.   if (!tree) return;
  250.  
  251.   HTREEITEM curr_selected=tree.GetDropHilightItem();
  252.   if (!curr_selected)
  253.     curr_selected=tree.GetSelectedItem();
  254.   if (curr_selected) {
  255.     /*
  256.     CString st=GetItemPath(curr_selected);
  257.   
  258.     CWnd* top_window=this;
  259.     while(top_window->GetParent())
  260.       top_window=top_window->GetParent();
  261.     ((CMainFrame*)top_window)->m_wndStatusBar.SetWindowTextCP(this, st);
  262.     */
  263.   }
  264.  
  265.     *pResult = 0;
  266. }
  267.  
  268. void CDirTreeView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 
  269. {
  270.   CTreeCtrl& tree=GetTreeCtrl();
  271.   if (!tree) return;
  272.   HTREEITEM curr_selected=tree.GetDropHilightItem();
  273.   if (!curr_selected)
  274.     curr_selected=tree.GetSelectedItem();
  275.   if (curr_selected) {
  276.     CString st=GetItemPath(curr_selected);
  277.     AfxMessageBox(st);
  278.   }
  279.   *pResult = 0;
  280. }
  281.  
  282.  
  283.  
  284. CString CDirTreeView::GetItemName(HTREEITEM position) {
  285.   CString st=GetTreeCtrl().GetItemText(position);
  286.   if (st.Find('<')) {
  287.     if (st.Right(2)==":>") {
  288.       st=st.Mid(st.Find('<')+1);
  289.       st=st.Left(st.GetLength()-1);
  290.     }
  291.   }
  292.   return st;
  293. }
  294.  
  295. CString CDirTreeView::GetItemPath(HTREEITEM position) {
  296.   if (position) {
  297.     HTREEITEM parent_it=GetTreeCtrl().GetParentItem(position);
  298.     CString st=GetItemName(position);
  299.     CString slash="";
  300.     if (GetTreeCtrl().ItemHasChildren(position))
  301.       slash="\\";
  302.     if (st.GetLength())
  303.       return GetItemPath(parent_it)+st+slash;
  304.     else
  305.       return GetItemPath(parent_it);
  306.   } else
  307.     return "";
  308. }
  309.  
  310. HTREEITEM CDirTreeView::GetPathItem(CString path,BOOL open,BOOL nofail,BOOL nohide,HTREEITEM rootposition) {
  311.   CTreeCtrl& tree=GetTreeCtrl();
  312.   if (!tree) return NULL;   /* error */
  313.   //
  314.   HTREEITEM return_value=NULL;
  315.   //
  316.   CString left="",right="";
  317.   int pos=path.Find('\\');
  318.   if (pos<0)
  319.     left=path;
  320.   else {
  321.     left=path.Left(pos);
  322.     right=path.Mid(pos+1);
  323.   }
  324.  
  325.   if (!nohide)
  326.     tree.ModifyStyle(WS_VISIBLE,0);
  327.   
  328.   HTREEITEM position;
  329.   if (!rootposition) {
  330.     rootposition=tree.GetRootItem();
  331.     /* position initiale */
  332.     position=rootposition;
  333.   } else {
  334.     // Ouvrir?
  335.     if (open) {
  336.       if (tree.ItemHasChildren(rootposition)) {        /* si enfants */
  337.         if (!(tree.GetItemState(rootposition,TVIF_STATE) & TVIS_EXPANDED)) {    /* si non ouvert */
  338.           /*tree.SetItemState(rootposition,TVIF_STATE,
  339.             tree.GetItemState(rootposition,TVIF_STATE) | TVIS_EXPANDED);
  340.             */
  341.           tree.Expand(rootposition,TVE_EXPAND);
  342.           RefreshDir(rootposition,TRUE);
  343.         }
  344.       }
  345.       
  346.     }
  347.  
  348.     /* position initiale */
  349.     position=tree.GetChildItem(rootposition);
  350.   }
  351.  
  352.   left.MakeLower();
  353.   while(position) {
  354.     CString st=GetItemName(position);
  355.     st.MakeLower();
  356.     if (st==left) {
  357.       if (right.GetLength())
  358.         position=GetPathItem(right,open,nofail,TRUE,position);
  359.       else
  360.         return_value=position;      // trouvΘ
  361.       position=NULL;
  362.     }
  363.     if (position)
  364.       position=tree.GetNextSiblingItem(position);
  365.   }
  366.  
  367.   // liste visible
  368.   if (!nohide) {
  369.     tree.ModifyStyle(0,WS_VISIBLE);
  370.     //RedrawWindow();
  371.     tree.GetParent()->RedrawWindow();
  372.   }
  373.   if (return_value)
  374.     return return_value;
  375.   else if (nofail)
  376.     return rootposition;
  377.   else
  378.     return NULL;
  379. }
  380.  
  381. BOOL CDirTreeView::EnsureVisible(CString path) {
  382.   if (!GetTreeCtrl()) return FALSE;   /* error */
  383. #if 0
  384.   /* Lancer refresh en arriΦre plan */
  385.   refreshPath=path;
  386.   StopTimer();
  387.   AfxBeginThread(CDirTreeViewRefresh,this);
  388.   return TRUE;
  389. #else
  390.   CWaitCursor wait;
  391.   HTREEITEM pos=GetPathItem(path,TRUE,TRUE);
  392.   if (pos) {
  393.     GetTreeCtrl().EnsureVisible(pos);
  394.   } else
  395.     return FALSE;
  396.   return TRUE;
  397. #endif
  398. }
  399.  
  400. BOOL CDirTreeView::EnsureVisibleBl(CString path) {
  401.   if (!GetTreeCtrl()) return FALSE;   /* error */
  402.   CWaitCursor wait;
  403.   int return_value=TRUE;
  404.   StopTimer();
  405.   HTREEITEM pos=GetPathItem(path,TRUE,TRUE);
  406.   if (pos) {
  407.     GetTreeCtrl().EnsureVisible(pos);
  408.   } else
  409.     return_value=FALSE;
  410.   StartTimer();
  411.   return return_value;
  412. }
  413.  
  414. void CDirTreeView::RefreshPos(HTREEITEM position) {
  415.   RefreshDir(position);
  416. }
  417.  
  418. BOOL CDirTreeView::RefreshDir(HTREEITEM position,BOOL nohide) {
  419.   CTreeCtrl& tree=GetTreeCtrl();
  420.   if (!tree) return FALSE;   /* error */
  421.  
  422.   CWaitCursor wait;
  423.   CString path=GetItemPath(position);
  424.   CString backup_visibles="\n";
  425.  
  426.   // Pour FindFirstFile/FindNextFile
  427.   WIN32_FIND_DATA find;
  428.   int type;
  429.   HANDLE h = FindFirstFile(path+"*.*",&find);
  430.  
  431.   // accessible
  432.   if (h!=INVALID_HANDLE_VALUE) {
  433.     // liste invisible
  434.     if (!nohide)
  435.       tree.ModifyStyle(WS_VISIBLE,0);
  436.  
  437.     { // backuper ΘlΘments visibles
  438.       HTREEITEM it=tree.GetChildItem(position);
  439.       int backup_visibles_count=0;
  440.       while(it) {
  441.         if (tree.ItemHasChildren(it)) {        /* si enfants */
  442.           if (tree.GetItemState(it,TVIF_STATE) & TVIS_EXPANDED) {    /* si ouvert */
  443.             backup_visibles+=(GetItemPath(it)+"\n");
  444.             backup_visibles_count++;
  445.           }
  446.         }
  447.         it=tree.GetNextVisibleItem(it);
  448.       }
  449.       if (!backup_visibles_count)
  450.         backup_visibles="";
  451.     }
  452.  
  453.     {  // effacer la liste
  454.       HTREEITEM it;
  455.       while(it=tree.GetChildItem(position))
  456.         tree.DeleteItem(it);
  457.     }
  458.     
  459.     // chargement de la liste
  460.     HTREEITEM last_dir_it=tree.GetRootItem();
  461.     for(type=0;type<2;type++) {
  462.       if (h != INVALID_HANDLE_VALUE) {
  463.         do {
  464.           if (!(find.dwFileAttributes  & (FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN))) {
  465.             if (strcmp(find.cFileName,"..")) {
  466.               if (strcmp(find.cFileName,".")) {
  467.                 HTREEITEM it=NULL;
  468.                 if (find.dwFileAttributes  & FILE_ATTRIBUTE_DIRECTORY ) {
  469.                   if (type==0) {
  470.                     if (IsWindow(tree.m_hWnd)) {
  471.                       it=tree.InsertItem(find.cFileName,position);
  472.                       tree.InsertItem("expanding..",it,TVI_SORT);
  473.                     }
  474.                   }
  475.                 } else {
  476.                   if (type==1) {
  477.                     if (IsWindow(tree.m_hWnd))
  478.                       it=tree.InsertItem(find.cFileName,position,last_dir_it);
  479.                   }
  480.                 }
  481.                 // changer icone
  482.                 if (it) {
  483.                   SHFILEINFO info;
  484.                   SHGetFileInfo(path+find.cFileName,0,&info,sizeof(info),SHGFI_SYSICONINDEX);
  485.                   //SHGetFileInfo(path+find.cFileName,0,&info,sizeof(info),SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_TYPENAME | SHGFI_SHELLICONSIZE | SHGFI_DISPLAYNAME | SHGFI_ATTRIBUTES); 
  486.                   if (IsWindow(tree.GetSafeHwnd()))
  487.                     tree.SetItemImage(it,info.iIcon,info.iIcon);
  488.                 }
  489.               }
  490.             }
  491.           }
  492.         } while(FindNextFile(h,&find));
  493.         FindClose(h);
  494.       }
  495.       if (type==0)
  496.         h = FindFirstFile(path+"*.*",&find);
  497.     }
  498.  
  499.     // restaurer ΘlΘments visibles
  500.     RestoreVisibles(position,backup_visibles);
  501.  
  502.     // liste visible
  503.     if (!nohide)
  504.       tree.ModifyStyle(0,WS_VISIBLE);
  505.   }/* **OLD 
  506.   else
  507.     tree.Expand(position,TVE_COLLAPSE);
  508.    */
  509.  
  510.   // Redessiner
  511.   if (!nohide)
  512.     GetParent()->RedrawWindow();
  513.   return (h!=INVALID_HANDLE_VALUE);
  514. }
  515.  
  516. void CDirTreeView::RestoreVisibles(HTREEITEM position,CString& backup_visibles) {
  517.   CTreeCtrl& tree=GetTreeCtrl();
  518.   if (!tree) return;   /* error */
  519.  
  520.   if (backup_visibles.GetLength()) {
  521.     // rΘouvrir les ΘlΘments visibles
  522.     HTREEITEM it=tree.GetChildItem(position);
  523.     while(it) {
  524.       if (backup_visibles.Find("\n"+GetItemPath(it)+"\n")>=0) {
  525.         tree.Expand(it,TVE_EXPAND);
  526.         RefreshDir(it,TRUE);       /* car appelΘ par RefreshDir lui mΩme */
  527.         RestoreVisibles(it,backup_visibles);
  528.       }
  529.       it=tree.GetNextSiblingItem(it);
  530.     }
  531.   }
  532. }
  533.  
  534.  
  535.  
  536. void CDirTreeView::StartTimer() {
  537.   if (!timer) {
  538.     //whandle=FindFirstChangeNotification("C:\\",TRUE,FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME);
  539.     BuildTrackHandles();
  540.     timer=SetTimer(WM_TIMER,1000,NULL);
  541.   }
  542. }
  543. void CDirTreeView::StopTimer() {
  544.   if (timer) {
  545.     DestroyTrackHandles();
  546.     KillTimer(timer);
  547.     timer=0;
  548.   }
  549. }
  550.  
  551. void CDirTreeView::DestroyTrackHandles() 
  552. {
  553.   /* Fermer handles actuels */
  554.   if (count_whandle) {
  555.     int i;
  556.     for(i=0;i<count_whandle;i++)
  557.       FindCloseChangeNotification(whandle[i]);
  558.     count_whandle=0;
  559.   }
  560. }
  561.  
  562. void CDirTreeView::BuildTrackHandles() 
  563. {
  564.   if (!GetTreeCtrl()) return;   /* error */
  565.   DestroyTrackHandles();
  566.   /* Lecture ΘlΘments du root visibles (non, c'est pas rΘcursif vu que ce sont les Θlts visibles) */
  567.   CTreeCtrl& it=GetTreeCtrl();
  568.   HTREEITEM pos=it.GetFirstVisibleItem();
  569.   while(pos) {
  570.     CString path=GetItemPath(pos);
  571.     CFileStatus status;
  572.     if (it.ItemHasChildren(pos)) {        /* surveiller si enfants */
  573.       if (it.GetItemState(pos,TVIF_STATE) & TVIS_EXPANDED) {    /* si ouvert */
  574.         if (CFile::GetStatus(path.Left(path.GetLength()-1),status)) {   // rΘpertoire (note: path sans le / final)
  575.           if (status.m_attribute & 0x10 ) {       /* directory = 0x10 */
  576.             whandle[count_whandle]=FindFirstChangeNotification(path,FALSE,FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME);
  577.             if (whandle[count_whandle] != INVALID_HANDLE_VALUE) {
  578.               pos_whandle[count_whandle]=pos;
  579.               count_whandle++;
  580.             }
  581.           }
  582.         }
  583.       }
  584.     }
  585.     pos=it.GetNextVisibleItem(pos);
  586.   }
  587.  
  588. }
  589.  
  590. void CDirTreeView::DoTrackHandles() 
  591. {
  592.   CTreeCtrl& tree=GetTreeCtrl();
  593.   if (!tree) return;   /* error */
  594.  
  595.   if (count_whandle) {
  596.     int r=(WaitForMultipleObjects(count_whandle,whandle,FALSE,0)-WAIT_OBJECT_0);
  597.     if ( (r>=0) && (r<count_whandle) ) {      // un item a changΘ
  598.       DestroyTrackHandles();
  599.       HTREEITEM pos=pos_whandle[r];
  600.       RefreshPos(pos);
  601.       tree.SetItemState(pos,TVIS_BOLD,TVIS_BOLD);
  602.       BuildTrackHandles();      /* probleme: on va en rater certains.. */ 
  603.       //FindNextChangeNotification(whandle[r]);
  604.     }
  605.     /*
  606.     int i;
  607.     for(i=0;i<count_whandle;i++)
  608.       FindNextChangeNotification(whandle[i]);
  609.     */
  610.   }
  611. }
  612.  
  613. void CDirTreeView::OnTimer(UINT nIDEvent) 
  614. {
  615.   DoTrackHandles();
  616.   CTreeView::OnTimer(nIDEvent);
  617. }
  618.  
  619. void CDirTreeView::OnShowWindow(BOOL bShow, UINT nStatus) 
  620. {
  621.   static BOOL detach_flag=FALSE;
  622.   if (detach_flag == bShow) return;
  623.   detach_flag=bShow;
  624.  
  625.   if (bShow) {
  626.     HIMAGELIST hSystemImageList;
  627.     SHFILEINFO SHFileInfo;
  628.     hSystemImageList = (HIMAGELIST)SHGetFileInfo("", 0, &SHFileInfo, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
  629.     if (!hSystemImageList) {
  630.       MessageBox("Error: SHGetFileInfo");
  631.       //return;
  632.     } else {
  633.       imagelist.Attach(hSystemImageList);
  634.     }
  635.   } else {
  636.     if (imagelist.m_hImageList) {
  637.       imagelist.Detach();
  638.       imagelist.m_hImageList=NULL;
  639.     }
  640.   }
  641.   //
  642.   CTreeView::OnShowWindow(bShow, nStatus);
  643.   if (bShow)
  644.     StartTimer();
  645.   else
  646.     StopTimer();
  647. }
  648.  
  649.  
  650. void CDirTreeView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
  651. {
  652.     TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
  653.     // TODO: Add your control notification handler code here
  654.  
  655.   if (pTVDispInfo->item.mask & TVIF_TEXT) {
  656.     if (pTVDispInfo->item.pszText) {
  657.       if (strlen(pTVDispInfo->item.pszText)) {
  658.         CString path=GetItemPath(pTVDispInfo->item.hItem);
  659.         if (path.Right(1)=="\\")
  660.           path=path.Left(path.GetLength()-1);
  661.         CString newpath=path.Left(path.ReverseFind('\\')+1)+pTVDispInfo->item.pszText;
  662.         if (path != newpath) {
  663.           if (!MoveFile(path,newpath)) {
  664.             AfxMessageBox("Unable to rename "+path+" to "+newpath+"!");
  665.           } else {
  666.             GetTreeCtrl().SetItemText(pTVDispInfo->item.hItem,pTVDispInfo->item.pszText);
  667.           }
  668.         }
  669.       }
  670.     }
  671.   }
  672.   
  673.  
  674.     *pResult = 0;
  675. }
  676.  
  677. void CDirTreeView::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) 
  678. {
  679.     TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
  680.   HTREEITEM selected=GetTreeCtrl().GetSelectedItem();
  681.     *pResult = 0;
  682.     
  683.   int key=pTVKeyDown->wVKey ;
  684.   switch(key) {
  685.   case 32:
  686.     if (selected) {
  687.       GetTreeCtrl().Expand(selected,TVE_TOGGLE);
  688.          *pResult = -1;
  689.     }
  690.     break;
  691.   case 13: case 10:
  692.     if (selected) {
  693.       GetTreeCtrl().Expand(selected,TVE_TOGGLE);
  694.          *pResult = -1;
  695.     }
  696.     break;
  697.   /*default:
  698.     printf("\a");
  699.     break;
  700.   */
  701.   }
  702.  
  703. }
  704.  
  705.  
  706.  
  707. /*
  708. IMPLEMENT_DYNAMIC(CDirTreeViewShellEx, CWinThread)
  709.  
  710. /////////////////////////////////////////////////////////////////////////////
  711. // CDirTreeViewShellEx
  712. BOOL CDirTreeViewShellEx::InitInstance() {
  713.   if (!ShellExecute(NULL,NULL,File,NULL,NULL,SW_SHOWNORMAL)) {
  714.   }
  715.   return 0;
  716. }
  717. */
  718. UINT CDirTreeViewShellEx( LPVOID pP ) {
  719.   CWaitCursor wait;
  720.   CString* File=(CString*) pP;
  721.   if (!ShellExecute(NULL,"open",*File,NULL,NULL,SW_SHOWNORMAL)) {
  722.   }
  723.   delete File;
  724.   return 0;
  725. }
  726.  
  727. UINT CDirTreeViewRefresh( LPVOID pP ) {
  728.   CDirTreeView* _this=(CDirTreeView*) pP;
  729.   if (!_this->redraw_in_progress) {
  730.     _this->redraw_in_progress=1;
  731.     _this->EnsureVisibleBl(_this->refreshPath);
  732.     _this->redraw_in_progress=0;
  733.   }
  734.   return 0;
  735. }
  736.  
  737.  
  738.  
  739. void CDirTreeView::OnKillFocus(CWnd* pNewWnd) 
  740. {
  741.     CTreeView::OnKillFocus(pNewWnd);
  742.     
  743.     CWnd* top_window=this;
  744.     while(top_window->GetParent())
  745.       top_window=top_window->GetParent();
  746.     SetWindowTextCP(((CMainFrame*)top_window)->m_wndStatusBar, "");
  747.     
  748. }
  749.  
  750.